package com.simplemonkeytest;



import com.jme.app.SimpleGame;
import com.jme.bounding.BoundingBox;
import com.jme.image.Texture;
import com.jme.input.MouseInput;
import com.jme.math.Quaternion;
import com.jme.math.Vector3f;
import com.jme.renderer.Renderer;
import com.jme.scene.Node;
import com.jme.scene.Spatial;
import com.jme.scene.shape.Capsule;
import com.jme.scene.state.BlendState;
import com.jme.scene.state.CullState;
import com.jme.scene.state.TextureState;
import com.jme.scene.state.ZBufferState;
import com.jme.system.DisplaySystem;
import com.jme.util.TextureManager;
import com.simplemonkey.Container;
import com.simplemonkey.ListeningContainer;
import com.simplemonkey.layout.BorderLayout;
import com.simplemonkey.layout.BorderLayoutData;
import com.simplemonkey.layout.CenteringLayout;
import com.simplemonkey.layout.RowLayout;
import com.simplemonkey.util.Spacing;
import com.simplemonkey.widgets.SimpleButton;
import com.simplemonkey.widgets.SimpleButtonListener;
import com.simplemonkey.widgets.TextureContainer;

public class ExampleApp extends SimpleGame {
	private Node hudNode;
	
    public static void main(String[] args) {
    	ExampleApp app = new ExampleApp();
        app.setConfigShowMode(ConfigShowMode.AlwaysShow);
        app.start();
    }
    
	
	protected void simpleInitGame() {
		display.setTitle("SimpleMonkeyGUI Test");
		input.setEnabled(false);//we don't want the cursor moving the camera, because we are using it for the gui.
		MouseInput.get().setCursorVisible(true);//show cursor
		super.graphNode.setCullHint(Spatial.CullHint.Always);
		
		/*For this application, my goal is to create a nice HUD that will take the form of a row 
		 * of buttons on the bottom of the screen, with one additional button on the top right hand
		 * corner of the screen.
		 * For the row on the bottom, I want to have a nice background running 
		 * behind the row.
		 */
				
		//Create a node in the ortho queue for the quads to go into.
		//It is good practice not to attach the hudNode to the root node, but to instead render 
		//it separately. Hud's don't tend to move a lot, or use Bounding culling, so they don't
		//need to be updated regularly like other Spatials. See the method simpleRender below.
		hudNode = new Node();
		hudNode.setCullHint(Spatial.CullHint.Never);
		hudNode.setRenderQueueMode(Renderer.QUEUE_ORTHO);
		hudNode.setLightCombineMode(Spatial.LightCombineMode.Off);
		
		//Give the hudNode an appropriate buffer state.
		ZBufferState bufferState = DisplaySystem.getDisplaySystem().getRenderer().createZBufferState();
		bufferState.setEnabled( true );
		bufferState.setFunction( ZBufferState.TestFunction.Always );//if CF_ALWAYS is selected, then ZOrder will be used to determine which pixel to display.
		bufferState.setWritable(true);
		hudNode.setRenderState(bufferState);
		
		//Set the hudNode to use transparency (useful if your textures have transparent portions)
		BlendState blendState = display.getRenderer().createBlendState();
		blendState.setBlendEnabled(true);
		blendState.setSourceFunctionAlpha(BlendState.SourceFunction.SourceAlpha);
		blendState.setDestinationFunctionAlpha(BlendState.DestinationFunction.OneMinusSourceAlpha);
		blendState.setTestEnabled(true);
		blendState.setTestFunction(BlendState.TestFunction.GreaterThan);
		blendState.setEnabled(true);
		hudNode.setRenderState(blendState);
		
		hudNode.updateRenderState();
	
		Texture up = TextureManager.loadTexture(getClass().getClassLoader().getResource("com/simplemonkey/data/samplebutton/capsuleButtonUp.png"),Texture.MinificationFilter.Trilinear,Texture.MagnificationFilter.Bilinear);
		Texture down = TextureManager.loadTexture(getClass().getClassLoader().getResource("com/simplemonkey/data/samplebutton/capsuleButtonDown.png"),Texture.MinificationFilter.Trilinear,Texture.MagnificationFilter.Bilinear);
		Texture hover = TextureManager.loadTexture(getClass().getClassLoader().getResource("com/simplemonkey/data/samplebutton/capsuleButtonHover.png"),Texture.MinificationFilter.Trilinear,Texture.MagnificationFilter.Bilinear);
		Texture background = TextureManager.loadTexture(getClass().getClassLoader().getResource("com/simplemonkey/data/samplebutton/background.png"),Texture.MinificationFilter.Trilinear,Texture.MagnificationFilter.Bilinear);
		
		//A good choice for the top level container is a listening container, as it can listen to jME Mouse events and pass them into the widget tree
		ListeningContainer mainContainer = new ListeningContainer();
		MouseInput.get().addListener(mainContainer);
		
		hudNode.attachChild(mainContainer.getSpatial());//attach the spatial in this container to the given node
		mainContainer.setLayoutManager(new BorderLayout());
		mainContainer.setSize(DisplaySystem.getDisplaySystem().getWidth(),DisplaySystem.getDisplaySystem().getHeight());
		
		Container northContainer = new Container();
		northContainer.setLayoutData(BorderLayoutData.NORTH);
		northContainer.setLayoutManager(new BorderLayout());
		mainContainer.addWidget(northContainer);
		
		SimpleButton exit = new SimpleButton("Exit",up,down,hover);
		exit.setLayoutData(BorderLayoutData.EAST);
		//The default size of simple buttons is the size of the textures applied to them.
		//I don't want them to shrink below that, so I will set shrinkable to be false.
		exit.setShrinkable(false);
		northContainer.addWidget(exit);
		
		exit.addButtonListener(new SimpleButtonListener()
		{
			
			public void buttonPressed() {
				System.exit(0);
			}
		});

		/*
		 * This is a just a container that has a quad in it, to which a texture can be applied.
		 * The quad will automatically scale as needed to fit the whole container.
		 */
		TextureContainer bottomContainer = new TextureContainer();
		bottomContainer.setTexture(background);
		bottomContainer.setLayoutData(BorderLayoutData.SOUTH);
		mainContainer.addWidget(bottomContainer);
		
		//I want to have the buttoms on the bottom laid out in a row, but I also want that row
		//to be centered horizontally in the container.
		bottomContainer.setLayoutManager(new CenteringLayout(CenteringLayout.CenterStyle.HORIZONTAL));
		
		Container rowContainer = new Container();
		rowContainer.setLayoutManager(new RowLayout());
		bottomContainer.addWidget(rowContainer);
		
		//Create a set of 5 buttons.
		for(int i = 0; i<5;i++)
		{
			SimpleButton button = new SimpleButton("Button "+i,up,down,hover);
			button.setShrinkable(false);
			button.setExpandable(false);
			
			//I want there to be some space, or margin, between each button:
			button.getSpacingAppearance().setMargin(new Spacing(0,5,5,0));
			//I also want to make the buttons a bit wider than they need to be:
			button.getSpacingAppearance().setPadding(new Spacing(0,10,10,0));
			
			rowContainer.addWidget(button);
		}
		
		//I want the bottom container to be higher than the buttons
		bottomContainer.getSpacingAppearance().setPadding(new Spacing(32,0,0,0));
		
		//Finally, layout everything.
		mainContainer.layout();
		
		
		
		//add some 3d objects to demonstrate the HUD's integration with normal jME:
		//(This is just one of the standard jME test cases)
	        t = new Capsule("Capsule", 40, 32, 16, 4, 10);
	        t.setModelBound(new BoundingBox());
	        t.updateModelBound();
	        
	        CullState cs = display.getRenderer().createCullState();
	        cs.setCullFace(CullState.Face.Back);
	        t.setRenderState(cs);
	        
	      
	        
	        rootNode.attachChild(t);
	        
	        TextureState ts = display.getRenderer().createTextureState();
	        ts.setEnabled(true);
	        ts.setTexture(TextureManager.loadTexture(getClass()
	                .getClassLoader().getResource("jmetest/data/images/Monkey.jpg"),
	                Texture.MinificationFilter.Trilinear,Texture.MagnificationFilter.Bilinear));
	        ts.getTexture().setWrap(Texture.WrapMode.Clamp);
	        t.setRenderState(ts);

	        lightState.setTwoSidedLighting(false);
		
		
	}
	
    private Quaternion rotQuat = new Quaternion();
    private float angle = 0;
    private Vector3f axis = new Vector3f(1, 1, 0).normalizeLocal();
    private Capsule t;
	
    protected void simpleUpdate() {
        if (timer.getTimePerFrame() < 1) {
            angle = angle + (timer.getTimePerFrame() * 1);
            if (angle > 360) {
                angle = 0;
            }
        }

        rotQuat.fromAngleNormalAxis(angle, axis);
        t.setLocalRotation(rotQuat);
    }

	
	protected void simpleRender() {
		//we want to render the hudNode by itself here.
	    display.getRenderer().draw(hudNode);
	}

}
